package com.gerryrun.lib_skin;

import android.app.Activity;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import java.lang.reflect.Constructor;
import java.util.HashMap;
import java.util.Observable;
import java.util.Observer;

/**
 * @author GerryRun
 * @data 2021/1/27
 * @email gerryin@163.com
 * @describe 自定义的LayoutInflateFactory
 */
public class SkinLayoutInflateFactory implements LayoutInflater.Factory2, Observer {

    //前缀
    private static final String[] sClassPrefixList = {
            "android.widget.",
            "android.webkit.",
            "android.app."
    };

    //记录 对应view的构造函数
    private static final Class<?>[] mConstructorSignature = new Class[]{
            Context.class, AttributeSet.class};

    private static final HashMap<String, Constructor<? extends View>> mConstructorMap =
            new HashMap<String, Constructor<? extends View>>();

    //当选择新皮肤后 需要替换view与之对应的属性，页面属性管理器
    private SkinAttribute skinAttribute;
    //用于获取窗口状态框的信息
    private Activity activity;

    public SkinLayoutInflateFactory(Activity activity) {
        this.activity = activity;
        skinAttribute = new SkinAttribute();
    }

    @Nullable
    @Override
    public View onCreateView(@Nullable View parent, @NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) {
        View view = createSDKView(name, context, attrs);
        if (null == view) {
            view = createView(name, context, attrs);
        }

        if (null != view) {
            //统计收集 需要换肤的View
            skinAttribute.look(view, attrs);
        }

        return view;
    }

    private View createSDKView(String name, Context context, AttributeSet attrs) {
        //如果包含，这说明是自定义view
        if (-1 != name.indexOf('.')) {
            return null;
        }
        for (int i = 0; i < sClassPrefixList.length; i++) {
            View view = createView(sClassPrefixList[i] + name, context, attrs);
            if (view != null)
                return view;
        }
        return null;
    }

    /**
     * 创建view
     *
     * @param name    name
     * @param context 上下文
     * @param attrs   属性集合
     * @return view
     */
    private View createView(String name, Context context, AttributeSet attrs) {
        Constructor<? extends View> constructor = findConstructor(context, name);
        try {
            return constructor.newInstance(context, attrs);
        } catch (Exception e) {
            return null;
        }
    }

    /**
     * 获取view的 构造方法并缓存
     *
     * @param context 上下文
     * @param name    name
     * @return 构造方法
     */
    private Constructor<? extends View> findConstructor(Context context, String name) {
        Constructor<? extends View> constructor = mConstructorMap.get(name);
        if (constructor == null) {
            Class<? extends View> clazz = null;
            try {
                clazz = context.getClassLoader().loadClass(name).asSubclass(View.class);
                constructor = clazz.getConstructor(mConstructorSignature);
                mConstructorMap.put(name, constructor);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
        }
        return constructor;
    }

    @Override
    public void update(Observable o, Object arg) {
        Log.e("TAG", "update: ");
        skinAttribute.applySkin();
    }

    @Nullable
    @Override
    public View onCreateView(@NonNull String name, @NonNull Context context, @NonNull AttributeSet attrs) {
        return null;
    }
}
